﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using CPETwit.Data.Entity;

namespace CPETwit.Data.Manager
{
    public class UserManager
    {
        //TODO
        public IEnumerable<User> GetFollowers(long _id)
        {
            var query = from user in ContextHelper.Context.User
                        from abonnement in ContextHelper.Context.Abonnement
                        where user.id == abonnement.follower
                        where abonnement.publisher == _id
                        where abonnement.follower != _id
                        select user;

            return query;
        }

        public IEnumerable<User> GetUnFollowers(long _id)
        {
            IEnumerable<User> all = GetAllUsersNotMe(_id);
            IEnumerable<User> followers = GetFollowers(_id);

            return all.Except<User>(followers);
        }

        public IEnumerable<User> GetPublishers(long _id)
        {
            var query = from user in ContextHelper.Context.User
                        from abonnement in ContextHelper.Context.Abonnement
                        where user.id == abonnement.publisher
                        where abonnement.follower == _id
                        where abonnement.publisher != _id
                        select user;

            return query;
        }

        public IEnumerable<User> GetUnPublishers(long _id)
        {
            IEnumerable<User> all = GetAllUsersNotMe(_id);
            IEnumerable<User> publisher = GetPublishers(_id);

            return all.Except<User>(publisher);
        }

        public IEnumerable<User> GetAllUsers()
        {
            var query = from user in ContextHelper.Context.User
                        select user;

            return query;
        }

        public IEnumerable<User> GetAllUsersNotMe(long id)
        {
            var query = from user in ContextHelper.Context.User
                        where user.id != id
                        select user;

            return query;
        }

        public IEnumerable<User> GetUsersById(params long[] _id)
        {

            var query = from user in ContextHelper.Context.User
                        where _id.Contains(user.id)
                        select user;

            return query;
        }


        public IEnumerable<User> GetUserByLogin(string _login)
        {

            var query = from user in ContextHelper.Context.User
                        where _login.ToLower() == user.login.ToLower()
                        select user;

            return query;
        }

        public IEnumerable<User> GetUsersByText(string _name)
        {
            //String[] allWords = _name.Split(' ');
            //var query = from user in ContextHelper.Context.User
            //            where allWords.Contains(user.name) || allWords.Contains(user.login)
            //            select user;

            var query = from user in ContextHelper.Context.User
                        where string.IsNullOrEmpty(_name) || (user.name.Contains(_name) || user.login.Contains(_name))
                        select user;

            return query;
        }



        public void CreateUser(User u)
        {
            ContextHelper.Context.User.AddObject(u);
            ContextHelper.Context.SaveChanges();
        }

        public void DeleteUser(User u)
        {
            ContextHelper.Context.User.DeleteObject(u);
            ContextHelper.Context.SaveChanges();
        }

        public void UpdateUser(User clientUser)
        {
            User serverUser = GetUsersById(clientUser.id).FirstOrDefault();
            if (serverUser == null) return;
            serverUser.name = clientUser.name;
            serverUser.birthdate = clientUser.birthdate;
            serverUser.description = clientUser.description;
            serverUser.email = clientUser.email;
            serverUser.sex = clientUser.sex;
            serverUser.login = clientUser.login;
            serverUser.password = clientUser.password;
            serverUser.avatar = clientUser.avatar;
            serverUser.web = clientUser.web;
            ContextHelper.Context.SaveChanges();
        }

        public bool IsEmailValid(string email)
        {
            var query = from user in ContextHelper.Context.User
                        where user.email == email
                        select user;

            return !query.Any();
        }

        public bool IsUserNameValid(string login)
        {
            var query = from user in ContextHelper.Context.User
                        where user.login.ToLower() == login.ToLower()
                        select user;

            return !query.Any();
        }

        public IEnumerable<User> GetTweetOwner(Tweet t)
        {
            var query = from user in ContextHelper.Context.User
                        from tweet in ContextHelper.Context.Tweet
                        where tweet.message == t.message
                        where tweet.userfrom == null
                        where user.id == tweet.twitter
                        select user;
            return query;
        }

        public void FollowUser(User follower, User publisher)
        {
            Abonnement abonnement = new Abonnement();
            abonnement.PublisherProperty = publisher;
            abonnement.FollowerProperty = follower;
            follower.AbonnementPublisherProperty.Add(abonnement);
            ContextHelper.Context.SaveChanges();
        }

        public IEnumerable<User> RechercheUser(Dictionary<string, string> filtres)
        {
            /*var where = "";
            string key;
            string value;
            foreach (var item in filtres.Keys)
            {
                key = item;
                value = filtres[key].ToLower();
                if(key != "age_min" && key != "age_max")
                    where += " where " + key + "==" + value;
                else
                {
                    value = DateTime.Today.AddYears(int.Parse(value)).ToShortDateString();
                    if (key == "age_min")
                        where += " where birthdate <= " + value;
                    else if (key == "age_max")
                        where += " where birthdate >= " + value;
                }
            }*/
            var query = from user in ContextHelper.Context.User
                        select user;

            string key;
            string value;

            foreach (var item in filtres.Keys)
            {
                key = item;
                value = filtres[key].ToLower();
                if(key == "sex")
                    query = query.Where(user => user.sex.ToLower() == value.ToLower());
                else if(key == "localization")
                    query = query.Where(user => user.localization.ToLower() == value.ToLower());
                else
                {
                    value = DateTime.Today.AddYears(int.Parse(value)).ToShortDateString();
                    if (key == "age_min")
                        query = query.Where(user => user.birthdate <= DateTime.Today.AddYears(int.Parse(value)*-1));
                    else if (key == "age_max")
                        query = query.Where(user => user.birthdate >= DateTime.Today.AddYears(int.Parse(value)*-1));
                }
            }



            return query;
        }
    }
}
